﻿using System.Collections.Generic;
using UnityEngine;

namespace Smart.Model
{
    [ObjectSystem]
    public class ComponentViewAwakeSystem : AwakeSystem<ComponentView,EventSystem,Transform>
    {
        public override void Awake(ComponentView self,EventSystem eventSystem,Transform parent)
        {
            self.Awake(eventSystem,parent);
        }
    }

    public class ComponentView : Component
    {
        public EventSystem EventSystem { get; private set; }
        public GameObject gameObject { get; private set; }
        public Transform Transform { get; private set; }

        Dictionary<long, Component> mComponents = new Dictionary<long, Component>();

        public virtual void Awake(EventSystem eventSystem,Transform parent)
        {
            EventSystem = eventSystem;
            gameObject = new GameObject(GetType().Name);
            Transform = gameObject.transform;
            Transform.SetParent(parent);
        }

        public T AddComponent<T>() where T : Component, new()
        {
            T component = new T();
            EventSystem.AddComponent(component);
            mComponents.Add(component.InstanceId, component);
            component.View = this;
            EventSystem.Awake(component);
            return component;
        }

        public T AddComponent<T,A>(A a) where T : Component, new()
        {
            T component = new T();
            EventSystem.AddComponent(component);
            mComponents.Add(component.InstanceId, component);
            component.View = this;
            EventSystem.Awake(component,a);
            return component;
        }

        public T AddComponent<T, A,B>(A a,B b) where T : Component, new()
        {
            T component = new T();
            EventSystem.AddComponent(component);
            mComponents.Add(component.InstanceId, component);
            component.View = this;
            EventSystem.Awake(component, a,b);
            return component;
        }

        public T AddComponent<T, A, B,C>(A a, B b,C c) where T : Component, new()
        {
            T component = new T();
            EventSystem.AddComponent(component);
            mComponents.Add(component.InstanceId, component);
            component.View = this;
            EventSystem.Awake(component, a, b,c);
            return component;
        }

        public override void Dispose()
        {
            if (Disposed)
            {
                return;
            }

            for(var it = mComponents.GetEnumerator();it.MoveNext();)
            {
                it.Current.Value.Dispose();
            }
            mComponents.Clear();
            mComponents = null;

            EventSystem = null;

            Transform = null;
            Object.Destroy(gameObject);
            gameObject = null;

            base.Dispose();
        }
    }
}